﻿using System.Windows.Forms;
using System.Collections.Generic;
using System;
using UtfprLibrary.ComponentModel.Security;
using UtfprLibrary.Windows.Forms.ComponentModel.Security;
using System.Data.Objects;
using System.Linq;

namespace UtfprLibrary.Windows.Forms.ComponentModel {
    internal partial class UtfprFormOperationsRestrictionEditor : Form {
        #region TODO

        private UtfprRestriction restriction = null;
        private ObjectContext context = null;
        private bool isLoaded = false;

        private object _value = null;
        public object Value { 
            get { return _value; } 
        }

        public UtfprFormOperationsRestrictionEditor(ObjectContext context) {
            //var key = context.ExecuteStoreQuery<int>("SELECT modulo_id FROM tb_seg_param", null).FirstOrDefault();

            //if (key == 0) {
            //    throw new Exception("Nenhum módulo encontrado nos parâmetros do sistema.");
            //}

            if (Configurations.DesignTime.UtfprSettings.Settings.Security.ModuleId == string.Empty) {
                throw new Exception("Nenhum módulo encontrado nos parâmetros do sistema.");
            }

            InitializeComponent();
            this.context = context;
        }

        #region Event Handlers

        private void UtfprFormRestrictionEditor_Load(object sender, EventArgs e) {
            try {
                populate();
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
            //lstData.DataSource = context.ExecuteStoreQuery<string>(
            //    Configuration.DesignTime.UtfprSettings.Settings.Security.Query, null).ToList();
        }

        private void utfprFunctionBindingSource_CurrentChanged(object sender, EventArgs e) {
            if (isLoaded && _bsUtfprFunction.Current != null) {
                var function = _bsUtfprFunction.Current as IUtfprKeyName;
                _bsUtfprOperation.DataSource = restriction.FunctionsAndOperations[function].ToList();
            }
        }

        private void btnOk_Click(object sender, System.EventArgs e) {
            _value = _bsUtfprOperation.Current;
        }

        private void btnCancel_Click(object sender, System.EventArgs e) {
            _value = null;
        }

        #endregion

        private IUtfprKeyName getModule(int moduleId) {
            var key = context.ExecuteStoreQuery<int>("SELECT id FROM tb_seg_sistema_modulo WHERE id = :p0", moduleId).SingleOrDefault();
            var name = context.ExecuteStoreQuery<string>("SELECT descricao FROM tb_seg_sistema_modulo WHERE id = :p0", moduleId).SingleOrDefault();

            return new UtfprKeyNameByDesign(key, name);
        }

        private List<IUtfprKeyName> getFunctions(int moduleKey) {
            var functions = new List<IUtfprKeyName>();

            var keys = context.ExecuteStoreQuery<int>("SELECT id FROM tb_seg_sistema_modulo_funcao WHERE tb_seg_sistema_modulo_id = :p0", moduleKey).ToList();

            foreach (var key in keys) {
                var systemFunctionId = context.ExecuteStoreQuery<int>("SELECT tb_seg_sistema_funcao_id FROM tb_seg_sistema_modulo_funcao WHERE id = :p0", key).SingleOrDefault();
                var name = context.ExecuteStoreQuery<string>("SELECT descricao FROM tb_seg_sistema_funcao WHERE id = :p0", systemFunctionId).SingleOrDefault();

                functions.Add(new UtfprKeyNameByDesign(key, name));
            }

            return functions;
        }

        private List<IUtfprKeyName> getOperations(int functionKey) {
            var operations = new List<IUtfprKeyName>();

            var keys = context.ExecuteStoreQuery<int>(
                "SELECT id FROM tb_seg_sistema_modulo_operacao WHERE sistema_modulo_funcao_id = :p0", functionKey).ToList();

            foreach (var key in keys) {
                var systemOperationId = context.ExecuteStoreQuery<int>("SELECT sistema_operacao_id FROM tb_seg_sistema_modulo_operacao WHERE id = :p0", key).SingleOrDefault();
                var basicOpKey = context.ExecuteStoreQuery<int>("SELECT tb_seg_operacao_basica_id FROM tb_seg_sistema_operacao WHERE id = :p0", systemOperationId).SingleOrDefault();
                var name = context.ExecuteStoreQuery<string>("SELECT descricao FROM tb_seg_operacao_basica WHERE id = :p0", basicOpKey).FirstOrDefault();
                operations.Add(new UtfprKeyNameByDesign(key, name));
            }

            return operations;
        }

        private UtfprRestriction getRestriction() {
            //var key = context.ExecuteStoreQuery<int>("SELECT modulo_id FROM tb_seg_param", null).FirstOrDefault();
            var key = int.Parse(Configurations.DesignTime.UtfprSettings.Settings.Security.ModuleId);
            var moduleKey = getModule(key).Key;
            var funcsAndOps = new Dictionary<IUtfprKeyName, IEnumerable<IUtfprKeyName>>();
            foreach (var function in getFunctions(moduleKey)) {
                funcsAndOps.Add(function, getOperations(function.Key));
            }

            return new UtfprRestriction(funcsAndOps);
        }

        private void populate() {
            restriction = getRestriction();
            var firstUserModule = restriction.FunctionsAndOperations.Keys.First();
            _bsUtfprFunction.DataSource = restriction.FunctionsAndOperations.Keys.ToList();
            _bsUtfprOperation.DataSource = restriction.FunctionsAndOperations[firstUserModule].ToList();
            isLoaded = true;
        }

        #endregion
    }
}